package com.powernode.dataservice.service;

import com.powernode.api.model.BidInfo;
import com.powernode.api.model.FinanceAccount;
import com.powernode.api.model.ProductInfo;
import com.powernode.api.service.InvestService;
import com.powernode.constants.YLBConstants;
import com.powernode.dataservice.mapper.BidInfoMapper;
import com.powernode.dataservice.mapper.FinanceAccountMapper;
import com.powernode.dataservice.mapper.ProductInfoMapper;
import com.powernode.util.CommonUtil;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;

@DubboService(interfaceClass = InvestService.class,version = "1.0.0")
public class InvestServiceImpl implements InvestService {

    @Autowired
    private FinanceAccountMapper financeAccountMapper;

    @Autowired
    private ProductInfoMapper productInfoMapper;

    @Autowired
    private BidInfoMapper bidInfoMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean investProduct(Integer uid, Integer productId, BigDecimal bidMoney) {
        /*if (true){
            throw new RuntimeException("扣除资金失败");
        }*/
        /*1验证数据*/
        FinanceAccount financeAccount = financeAccountMapper.selectByUid(uid);
        if (financeAccount!=null){
            /*资金是否足够*/
            /*在工具类中添加一个 比较  BigDecimal 类型大小的 方法*/
            if (CommonUtil.ge(financeAccount.getAvailableMoney(),bidMoney)){
                /*考虑 高并发  使用 悲观锁*/
                ProductInfo productInfo = productInfoMapper.selectByIdForUpdate(productId);
                /*产品 是否 时为满标状态*/
                if (productInfo!=null&&productInfo.getProductStatus()== YLBConstants.PRODUCT_STATUS_NOTFULL){
                    /*产品剩余资金是否可投*/
                    if (checkMoney(productInfo,bidMoney)){
                        /*扣除资金*/
                        int rows = financeAccountMapper.reduceMoney(uid,bidMoney);
                        if (rows<1){
                            /*如果 不成功 应该 回滚  有异常*/
                            throw new RuntimeException("扣除资金失败");
                        }
                        /*扣除产品的剩余金额*/
                        rows = productInfoMapper.reduceLeftMoney(productId,bidMoney);
                        if (rows<1){
                            throw new RuntimeException("扣除产品可投资金额失败");
                        }
                        /*创建投资记录*/
                        BidInfo bidInfo = new BidInfo();
                        bidInfo.setUid(uid);
                        bidInfo.setProdId(productId);
                        bidInfo.setBidMoney(bidMoney);
                        bidInfo.setBidTime(new Date());
                        bidInfo.setBidStatus(YLBConstants.BID_STATUS_SUCCESS);
                        bidInfoMapper.insertSelective(bidInfo);
                        /*判断产品 购买后 是否 满标*/
                        productInfo= productInfoMapper.selectByPrimaryKey(productId);
                        /*是否卖完了*/
                        if (productInfo.getLeftProductMoney().compareTo(new BigDecimal("0"))==0){
                            /*卖完了   将 产品的状态 修改为 满标*/
                           rows = productInfoMapper.updateFullTimeStatus(productId,new Date());
                           if (rows<1){
                               throw new RuntimeException("更新满标状态失败");
                           }
                        }
                        /*没卖完 无需操作*/
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * @param productInfo  产品
     * @param bidMoney  投资金额
     * @return
     */
    /*验证投资金额*/
    private boolean checkMoney(ProductInfo productInfo,BigDecimal bidMoney){
        /*判断 投资金额 是否满足 100的倍数*/
        if (bidMoney.intValue()%100!=0||bidMoney.intValue()<100){
            return false;
        }
        /*判断产品剩余可投 是否 可以购买*/
        if (!CommonUtil.ge(productInfo.getLeftProductMoney(),bidMoney)){
            return false;
        }
        /*产品 的最大投资金额 是否 大于 购买金额*/
        if (!CommonUtil.ge(productInfo.getBidMaxLimit(),bidMoney)){
            return false;
        }
        /*产品的最小投资金额 是否 小于 购买金额*/
        if (!CommonUtil.ge(bidMoney,productInfo.getBidMinLimit())){
            return false;
        }
        return true;
    }
}
